#include "demuxmedia.h"
#include <QDebug>

DemuxMedia::DemuxMedia() {
    avFmtCtx = avformat_alloc_context();
}

DemuxMedia::~DemuxMedia()
{
    if(avFmtCtx != nullptr){
        avformat_close_input(&avFmtCtx);
        avformat_free_context(avFmtCtx);
        qDebug() << "DemuxMedia::release avFmtCtx";
    }
}

bool DemuxMedia::openMediaStream(const char *url)
{
    int ret = -1;
    if(avFmtCtx == nullptr){
        qDebug() << "DemuxMedia::avFmtCtx == nullptr";
        return false;
    }

    //打开输入流,自动寻找匹配的AVInputFormat格式
    ret = avformat_open_input(&avFmtCtx,url,nullptr,nullptr);
    if(ret != 0){
        char buf[1024] = { 0 };
        av_strerror(ret, buf, sizeof(buf) - 1);
        qDebug() << "open " << url << " failed! :" << buf;
        qDebug() << "DemuxMedia::avformat_open_input error";
        avformat_free_context(avFmtCtx);
        return false;
    }

    //读取媒体的部分数据，从而获取多媒体流的信息
    ret = avformat_find_stream_info(avFmtCtx,nullptr);
    if(ret < 0){
        qDebug() << "DemuxMedia::avformat_find_stream_info error";
        avformat_close_input(&avFmtCtx);
        avformat_free_context(avFmtCtx);
        return false;
    }
    //打印码流信息
    av_dump_format(avFmtCtx,0,url,0);

    //获取音频流索引
    audioIndex = av_find_best_stream(avFmtCtx,AVMediaType::AVMEDIA_TYPE_AUDIO,-1,-1,nullptr,0);
    //获取视频流索引
    videoIndex = av_find_best_stream(avFmtCtx,AVMediaType::AVMEDIA_TYPE_VIDEO,-1,-1,nullptr,0);

    //这里获取不到解码器信息，解码器信息在流里边
    qDebug() << "DemuxMedia::avFmtCtx->audio_codec_id" << avFmtCtx->audio_codec_id;
    qDebug() << "DemuxMedia::avFmtCtx->streams[audioIndex]->codecpar->codec_id" <<avFmtCtx->streams[audioIndex]->codecpar->codec_id;//86018
    qDebug() << "DemuxMedia::打开码流成功";
    return true;
}

AVPacket *DemuxMedia::readPacket()
{
    if(avFmtCtx == nullptr){
        qDebug() << "DemuxMedia::readPacket() avFmtCtx == nullptr";
        return nullptr;
    }
    //要加入到缓冲队列中所以要每个packet都开辟空间
    AVPacket *pkt = av_packet_alloc();
    //读取一帧
    int ret = av_read_frame(avFmtCtx, pkt);
    if (ret != 0)
    {
        char buf[1024] = { 0 };
        av_strerror(ret, buf, sizeof(buf) - 1);
        qDebug() << "DemuxMedia::readPacket()" << buf;
        av_packet_free(&pkt);
        return nullptr;
    }
    //pts转换为毫秒
    pkt->pts = pkt->pts*(1000 * (r2d(avFmtCtx->streams[pkt->stream_index]->time_base)));
    pkt->dts = pkt->dts*(1000 * (r2d(avFmtCtx->streams[pkt->stream_index]->time_base)));
    return pkt;
}

int DemuxMedia::getAudioIndex()
{
    return audioIndex;
}

int DemuxMedia::getVideoIndex()
{
    return videoIndex;
}

AVCodecParameters *DemuxMedia::copyAVCodecParams(int streamIndex)
{
    AVCodecParameters* params = avcodec_parameters_alloc();
    avcodec_parameters_copy(params, avFmtCtx->streams[streamIndex]->codecpar);
    return params;
}
